#ifndef H_A2DDT
#define H_A2DDT
#define A2DDT_H

/* COMMON STRUCTURES AND CONSTANTS DESCRIPTION */

#ifndef H_A2TR
#include "a2tr.h"
#endif

/*  DATA DESCRIPTION SYSTEM  CODES  OF  THE PSEUDOSTATES AND ERRORS */
/*---------------------- pseudostates ------------------------------*/
#define ED_SM   (-9 )                                /* empty level */
#define ED_SA   (-10)                          /* no current vertex */
#define ED_SB   (-11)                            /* level beginning */
#define ED_SE   (-12)                                  /* level end */
#define ED_SP   (-13)                           /* protected vertex */
#define ED_SV   (-14)                       /* vertical pseudostate */
#define ED_FERR (-14)      /* boundary code of insignificant errors */
/*=================== serious errors ===============================*/
/*---------------- data description tree opening -------------------*/
#define ED_OR   (-51)             /* improper format of root record */
#define ED_OM   (-53)                          /* not enough memory */
#define ED_OE   (-54)                                 /* empty file */
/*---------------- data description tree closing -------------------*/
#define ED_CT   (-55)                 /* incorrect pointer or table */
/*-------------------- operations of movement ----------------------*/
#define ED_FK   (-56)                   /* there is no required key */
#define ED_MAR  (-57)        /* improper movement or action in root */
#define ED_MS   (-58)                      /* invalid movement code */
#define ED_LN   (-59)                       /* invalid level number */
#define ED_MST  (-60)           /* movement down in terminal vertex */
#define ED_MK   (-61)                           /* invalid key type */
#define ED_NA   (-62)                  /* the vertex is not indexed */
/*-------------------- read/write operations -----------------------*/
#define ED_MD   (-63)                         /* invalid value type */
#define ED_ANV  (-64)        /* vertex with this key already exists */
#define ED_AEV  (-65)                     /* no vertex for deleting */
#define ED_UK   (-66)                          /* improper changing */
#define ED_AF   (-67)           /* the array element already exists */
#define ED_AMA  (-68)      /* the array may not be element of array */
#define ED_KE   (-69)                     /* the key already exists */
#define ED_KN   (-70)                           /* array has no key */
#define ED_AE   (-71)                   /* the index already exists */
#define ED_OK   (-72)         /* the key shouldn't be on this level */
#define ED_PP   (-73)                         /* pointer to pointer */
#define ED_NP   (-74)              /* there is no vertex pointed to */
#define ED_RC   (-75)                /* recursive copying or moving */
#define ED_PC   (-76)                  /* erroneous pointer to copy */
#define ED_DT   (-77)               /* ambiguous type specification */
#define ED_AC   (-78)                     /* invalid operation code */

/* ACCESS TO THE CONTROL BLOCK DATA AND ENVIRONMENT PARAMETERS */

/*------------------- set message level ---------------------*/
#define DDTERMSGP(pddt,t) pddt->emsg=t
#define EM_S     1     /* messages about serious errors only */
#define EM_T     4    /* messages about pseudostates as well */
/*------------------ read message level ---------------------*/
#define DDTERMSG(pddt) (pddt->emsg)
/*-------------------- set trace level ----------------------*/
#if !defined(__FOR_WINDOWS__) && !defined(__FOR_WIN32__)
# define DDTTRACEP(pddt,t,s)                      \
	 a2ddttrp = a2ddttr,                           \
    strncpy(pddt->trid, s, sizeof(pddt->trid)-1), \
    pddt->trc = t;
#else
# define DDTTRACEP(pddt,t,s)                      \
    strncpy(pddt->trid, s, sizeof(pddt->trid)-1), \
    pddt->trc = t;
#endif
/*------------------- read trace level ----------------------*/
#define DDTTRACE(pddt) (pddt->trc)
/*---- set treatment regime of references to description ----*/
#define DDTASP(pddt,t) (pddt->as=(char)((pddt->as&~1)|t))
/*--- read treatment regime of references to description ----*/
#define DDTAS(pddt) (pddt->as&1)
/*------- set treatment regime of references to value -------*/
#define DDTREFP(pddt,t) (pddt->as=(pddt->as&~2)|(t<<1))
/*------ read treatment regime of references to value -------*/
#define DDTREF(pddt) ((pddt->as&2)>>1)
/*------------- level number from tree root -----------------*/
#define DDTLVL(pddt) (pddt->lvl)
/*----------- level number from stack header ----------------*/
#define DDTGLVL(pddt) (pddt->gllvl)
/*---------------------- value type -------------------------*/
#define DDTVTYPE(pddt) pddt->vx[pddt->icl].type
/*--------------- key type (for key level) ------------------*/
#define DDTKTYPE(pddt) pddt->vx[pddt->icl].ktype
/*------------------ not 0 if key level ---------------------*/
#define DDTKLVL(pddt) ((pddt->vx[pddt->icl].k) & 4)
/*---------------- not 0 if vertex is key -------------------*/
#define DDTKN(pddt) ((pddt->vx[pddt->icl].k) & 1 )
/*-------------- not 0 if vertex is indexed -----------------*/
#define DDTATR(pddt) (((pddt->vx[pddt->icl].k)>>4) & 3 )
/*----------------- output format adress --------------------*/
#define DDTPF(pddt) (pddt->vx[pddt->icl].pf)
/*--- ddt-key (internal system identifier) of the vertex ----*/
#define DDTDKEY(pddt) pddt->vx[pddt->icl].dk
/*----------- ddt-key of the father of the vertex -----------*/
#define DDTUT(pddt) pddt->vx[pddt->icl].u_t
/*---------------------- buffer size ------------------------*/
#define DDTBSIZE(i) a2ddtbs=i
/*------------- current transaction type --------------------*/
#define DDTTRANS(pddt) (pddt->n->pdf->trType1)

#define chkkey(c) (0x01&(c))           /* 1-st bit - mark of */
#define mrkkey(c,t) ((0xFE&(c))|(t))   /*         key vertex */
#define chkatr(c)    (0x01&((c)>>4))   /* 5-th bit - mark of */
#define mrkatr(c,t) ((0xEF&(c))|((t)<<4))/*   indexed vertex */
#define galvl(c) (0x01&((c)>>5))   /* 6-th - mark of indexed */
#define palvl(c,t) ((0xDF&(c))|((t)<<5))        /* key level */


/*   MACROOPERATIONS  FOR  DATA  MANIPULATION  */

       /* single r/w operation on whole vertex */

#define DDTSWKD(err,pdd,mv,ac,keyt,key,dtp,dta) { \
*err=a2ddtc( pdd, mv, ac, keyt, key, dtp, dta, 3 ) ; }

/*  int   *err   - pointer to error code ;
    TREE  *pdd   - pointer to process control table ;
    char  mv     - movement code ;
    char  ac     - r/w operation code ;
    char  keyt   - key type ;
    char  *key   - pointer to key ;
    char  dtp    - value type ;
    char  *dta   - pointer to value ;

**  The parameters of the other macrooperations are analogous
    to this set.
*/

          /* single r/w operation on key */
#define DDTSWK(err,pdd,mv,ac,keyt,key) { \
*err=a2ddtc( pdd, mv, ac, keyt, key, 0, NULL, 1 ) ; }

          /* single r/w operatin on value */
#define DDTSWD(err,pdd,mv,ac,dtp,dta) { \
*err=a2ddtc( pdd, mv, ac, 0, NULL, dtp, dta, 2 ) ; }

         /* single r/w operation of movement */
#define DDTSW(err,pdd,mv,ac) { \
*err=a2ddtc( pdd, mv, ac, 0, NULL, 0, NULL, 0 ) ; }

         /* single r/o operation on whole vertex */
#define DDTSRKD(err,pdd,mv,ac,keyt,key,dtp,dta) { \
*err=a2ddtrc( pdd, mv, ac, keyt, key, dtp, dta, 3 ) ; }

         /* single r/o operation on key */
#define DDTSRK(err,pdd,mv,ac,keyt,key) {  \
*err=a2ddtrc( pdd, mv, ac, keyt, key, 0, NULL, 1 ) ; }

         /* single r/o operatin on value */
#define DDTSRD(err,pdd,mv,ac,dtp,dta) { \
*err=a2ddtrc( pdd, mv, ac, 0, NULL, dtp, dta, 2 ) ; }

         /* single r/o operation of movement */
#define DDTSR(err,pdd,mv,ac) { \
*err=a2ddtrc( pdd, mv, ac, 0, NULL, 0, NULL, 0 ) ; }

       /* copying or movement the subtree */
#define DDTCPY(err,mv,ptr1,ptr2) { \
     *err=a2ddtc( ptr1, S_O, mv, 0, NULL, 0, &ptr2, 2 ) ;   }

       /* copying the process */
#define DDTDUP(err,ptr1,ptr2) {    \
     *err=a2ddtrc( ptr1, S_O, D_P, 0, NULL, 0, &ptr2, 2 ) ; }

       /* removing the copy of process */
#define DDTDLT(err,ptr1,ptr2) {    \
     *err=a2ddtrc( ptr1, S_O, R_C, 0, NULL, 0, &ptr2, 2 ) ; }

       /* saving the current point of process */
#define DDTSAV(err,pt) {           \
     *err=a2ddtrc( pt, S_O, S_P, 0, NULL, 0, NULL, 0 ) ;    }

       /* restoring the current point of process */
#define DDTRST(err,pt) {           \
     *err=a2ddtrc( pt, S_O, R_P, 0, NULL, 0, NULL, 0 ) ;    }

       /* check point */
#define DDTCP(err,pd,fc) a2dacp( err, ((DDT*)pd)->k->pdf, fc)

         /* group r/o operation on whole vertex */
#define DDTGRKD(pdd,x,mv,ac,keyt,key,dtp,dta) {  x->m=mv; x->d=ac;   \
 x->kt=keyt; x->k=(char*)key; x->vt=dtp; x->v=(char*)dta; x->p=NULL; \
 if (pdd->cm.p!=NULL)  pdd->cm.p->p=x ; pdd->cm.p=x; }

           /* group r/o operation on key */
#define DDTGRK(pdd,x,mv,ac,keyt,key) { x->p=NULL; x->m=mv; x->d=ac;  \
 x->kt=keyt; x->k=(char*)key;                                        \
 if (pdd->cm.p!=NULL) pdd->cm.p->p=x ; pdd->cm.p=x; }

         /* group r/o operation on value */
#define DDTGRD(pdd,x,mv,ac,dtp,dta) { x->p=NULL; x->m=m; x->d=ac;    \
 x->vt=dtp; x->v=(char*)dta ;                                        \
 if (pdd->cm.p!=NULL) pdd->cm.p->p=x ; pdd->cm.p=x; }

         /* group r/o operation of movement */
#define DDTGR(pdd,x,mv,d1) { x->p=NULL; x->m=mv; x->d=d1;            \
  if (pdd->cm.p!=NULL) pdd->cm.p->p=x ; pdd->cm.p=x; }

         /* start of execution of group r/o operation */
#define DDTGREX(err,pdd,x) { *err=a2ddt( pdd, x ) ; pdd->cm.p=NULL; }


          /* group r/w operation on whole vertex */
#define DDTGWKD(pdd,x,mv,ac,keyt,key,dtp,dta) {  x->m=mv; x->d=ac;   \
 x->kt=keyt; x->k=(char*)key; x->vt=dtp; x->v=(char*)dta; x->p=NULL; \
 if (pdd->cm.p!=NULL)  pdd->cm.p->p=x ; pdd->cm.p=x; }

          /* group r/w operation on key */
#define DDTGWK(pdd,x,mv,ac,keyt,key) { x->p=NULL; x->m=mv; x->d=ac;  \
 x->kt=keyt; x->k=(char*)key;                                        \
 if (pdd->cm.p!=NULL) pdd->cm.p->p=x ; pdd->cm.p=x; }

          /* group r/w operation on value */
#define DDTGWD(pdd,x,mv,ac,dtp,dta) { x->p=NULL; x->m=m; x->d=ac;    \
 x->vt=dtp; x->v=(char*)dta ;                                        \
 if (pdd->cm.p!=NULL) pdd->cm.p->p=x ; pdd->cm.p=x; }

          /* group r/w operation of movement */
#define DDTGW(pdd,x,mv,d1) { x->p=NULL; x->m=mv; x->d=d1;            \
  if (pdd->cm.p!=NULL) pdd->cm.p->p=x ; pdd->cm.p=x; }

          /* start of execution of group r/w operation */
#define DDTGWEX(err,pdd,x) { *err=a2ddt( pdd, x ) ; pdd->cm.p=NULL; }

#ifndef H_A2NIKA

#ifdef __cplusplus
extern "C" {
#endif

/* internal trace utilities */
extern int (*a2ddttrp)( int err, DDT *pd, TCOMMAND *pc ) ;
extern int a2ddttr( int err, DDT *pd, TCOMMAND *pc ) ;

                /*  USER  ENTREES  DEFINITION  */

/*-------------- DATA DESCRIPTION TREE OPENING ---------------------*/
DDT  *a2ddtop( int *perr, char *file, char disp, int *pblks,
                                                         void *pass );
/* perr - pointer to error code ; file - filename ;
   disp - opening disposition ; pblks - pointer to block size ;
   user - reserved ;
   returns a pointer to process control table.
*/

/*-------------- DATA DESCRIPTION TREE CLOSING ---------------------*/
int a2ddtcl( DDT *ptddt );

/* pddt - pointer to the control table. */

/*--------- open user process in user information branch -----------*/
             /* with optional creation of the branch */

TREE *a2ddtust( int *perr, DDT *pdod, long *pkey, long usk );

/* perr - pointer to error code ; pdod - pointer to the original
   process control table ;
   pkey - ddt-key of vertex requared ;
   usk - key of the branch requared ;
   user - reserved ;
   returns a pointer to TREE process control table.
*/

/*--------- open user process in user information branch -----------*/
                     /* without creation */

TREE *a2ddtus ( int *perr, DDT *pdod, long *pkey, char act, long usk);

/* perr - pointer to error code ; pdod - pointer to the original
   process control table ;
   pkey - ddt-key of vertex requared ;
   usk - key of the branch requared ;
   user - reserved ;
   returns a pointer to TREE process control table.
*/

/*------------------- removing of user process ---------------------*/

void a2ddtret( int *perr, TREE *pdod );

/* perr - pointer to error code ; pdod - pointer to the original
   process control table ;
   remuves process created by a2ddtus() or a2ddtust().
*/

/*---------------------- ddt-key comparing -------------------------*/

int a2ddtcmp( long *p1, long *p2, char type );

/* p1, p2 - pointer to the keys ;
   type - type of the keys (TY_I or TY_T ) ;
   returns result analogous to the strcmp().
*/


/*------------------- access to the r/o operations -----------------*/
/*     entrees used in the data manipulation makrooperations        */

int a2ddtr( DDT *pcddt, TCOMMAND *pcommand );
int a2ddtrc( DDT *ptr, char m1, char a,
	     char kt1, void *k1, char vt1, void *v1, char arg ) ;

/*------------------- access to the r/w operations -----------------*/
/*     entrees used in the data manipulation makrooperations        */

int a2ddt( DDT *pcddt, TCOMMAND *pcommand ) ;
int a2ddtc( DDT *ptr, char m1, char a,
	    char kt1, void *k1, char vt1, void *v1, char arg ) ;

#ifdef __cplusplus
}
#endif

#endif

#endif /* H_A2DDT */
